import random
import time

import pytest
import requests
import json
from unittest.mock import patch, MagicMock

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"  # 实际测试中应从环境变量获取
SECRET_KEY = "your-secret-key"  # 实际测试中应从环境变量获取


def generate_signature(params, secret_key):
    """生成签名（模拟实现）"""
    # 实际签名算法需要按照腾讯云API规范实现
    # 这里仅作模拟
    return "mock-signature"


def send_request(action, params):
    """发送API请求（模拟实现）"""
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestInquiryPriceResizeDisk:
    @patch('requests.post')
    def test_inquiry_success(self, mock_post):
        """测试成功询价"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "RequestId": "1234567890",
                "Price": {
                    "OriginalPrice": 100.0,
                    "DiscountPrice": 80.0
                }
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Price" in result["Response"]
        assert "OriginalPrice" in result["Response"]["Price"]

    @patch('requests.post')
    def test_inquiry_internal_error(self, mock_post):
        """测试内部错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalError.TradeUnknownError",
                    "Message": "内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InternalError.TradeUnknownError"

    @patch('requests.post')
    def test_inquiry_insufficient_balance(self, mock_post):
        """测试账户余额不足"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidAccount.InsufficientBalance",
                    "Message": "账户余额不足"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidAccount.InsufficientBalance"

    @patch('requests.post')
    def test_inquiry_unpaid_order(self, mock_post):
        """测试账户有未支付订单"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidAccount.UnpaidOrder",
                    "Message": "账户有未支付订单"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidAccount.UnpaidOrder"

    @patch('requests.post')
    def test_inquiry_unsupported_instance(self, mock_post):
        """测试不支持的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstance.NotSupported",
                    "Message": "不被支持的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-unsupported",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidInstance.NotSupported"

    @patch('requests.post')
    def test_inquiry_malformed_instance_id(self, mock_post):
        """测试无效格式的实例ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.Malformed",
                    "Message": "无效实例ID。指定的实例ID格式错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "invalid-ins-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.Malformed"

    @patch('requests.post')
    def test_inquiry_not_found_instance(self, mock_post):
        """测试实例不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "没有找到相应实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-not-found",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_inquiry_invalid_parameter_value(self, mock_post):
        """测试参数取值错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue",
                    "Message": "参数取值错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": -100  # 负数大小
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue"

    @patch('requests.post')
    def test_inquiry_malformed_instance_id_format(self, mock_post):
        """测试实例ID格式不符合要求"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InstanceIdMalformed",
                    "Message": "实例ID不合要求，请提供规范的实例ID"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "INS-VALID-ID",  # 大写字母不合法
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InstanceIdMalformed"

    @patch('requests.post')
    def test_inquiry_malformed_snapshot_id(self, mock_post):
        """测试快照ID格式不符合要求"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.SnapshotIdMalformed",
                    "Message": "快照ID不合要求，请提供规范的快照ID"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100,
            "SnapshotId": "SNAP-VALID-ID"  # 假设使用了快照参数且格式错误
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.SnapshotIdMalformed"

    @patch('requests.post')
    def test_inquiry_unsupported_zone(self, mock_post):
        """测试不支持的可用区"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.ZoneNotSupported",
                    "Message": "请求不支持该可用区"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskSize": 100,
            "Zone": "unsupported-zone"
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.ZoneNotSupported"

    @patch('requests.post')
    def test_inquiry_missing_parameter(self, mock_post):
        """测试缺少必要参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter",
                    "Message": "缺少参数错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {}  # 空参数
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "MissingParameter"

    @patch('requests.post')
    def test_inquiry_missing_at_least_one(self, mock_post):
        """测试至少需要一个参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.AtLeastOne",
                    "Message": "缺少必要参数，请至少提供一个参数"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {}  # 空参数
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "MissingParameter.AtLeastOne"

    @patch('requests.post')
    def test_inquiry_cloud_disk_unavailable(self, mock_post):
        """测试云盘不可用"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "ResourceInsufficient.CloudDiskUnavailable",
                    "Message": "云盘参数不符合规范"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-unavailable",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "ResourceInsufficient.CloudDiskUnavailable"

    @patch('requests.post')
    def test_inquiry_corrupted_instance(self, mock_post):
        """测试永久故障的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateCorrupted",
                    "Message": "请求不支持永久故障的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-corrupted",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateCorrupted"

    @patch('requests.post')
    def test_inquiry_stopped_instance(self, mock_post):
        """测试已关机的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateStopped",
                    "Message": "请求不支持已关机的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-stopped",
            "DiskId": "disk-valid-id",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateStopped"

    @patch('requests.post')
    def test_inquiry_invalid_disk(self, mock_post):
        """测试不支持的磁盘"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InvalidDisk",
                    "Message": "不支持指定的磁盘"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-invalid",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InvalidDisk"

    @patch('requests.post')
    def test_inquiry_migrating_disk(self, mock_post):
        """测试正在迁移的磁盘"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.LocalDiskMigratingToCloudDisk",
                    "Message": "不支持正在本地盘转云盘的磁盘"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-migrating",
            "DiskSize": 100
        }
        result = send_request("InquiryPriceResizeDisk", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.LocalDiskMigratingToCloudDisk"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()